home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <graphics/view.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
- #include <dos.h>
- #include <proto/dos.h>
- #include <math.h>
- #include <exec/devices.h>
- #include <devices/audio.h>
- #include <hardware/custom.h>
-
- #define CUE 0
- #define BLK 5
- #define GREENBAIZE 0
- #define BLUEBAIZE 1
-
- #define BASE 200 /* V.important constant. Used in ALL physical calcs. */
- #define BASESP 1000
- #define BASEII 4 /* For root calcs which need plenty of precision */
-
- #define TABLELENGTH (272 * BASE) /* 272 is actual length in pixels */
- #define TABLEWIDTH ((TABLELENGTH * 5 / 8)-BASE)
-
- #define X1CORNER 24
- #define Y1CORNER 62
- #define X2CORNER (X1CORNER + TABLELENGTH / BASE)
- #define Y2CORNER (Y1CORNER + TABLEWIDTH / BASE)
-
- #define BALLRADIUS (7 * BASE) /* 7 pixels */
- #define BALLDIAMETER (BALLRADIUS * 2)
- #define SCRNBALLDIAMETER (BALLDIAMETER / BASE)
- #define SEMICIRCRAD (TABLEWIDTH/6)
- #define PLACEPACK (TABLELENGTH * 5 / 8)
- #define PACKHORIZSEP (BALLDIAMETER - 2*BASE)
- #define POCKET (BALLRADIUS + 5*BASE)
- #define SCRNPOCKET (POCKET / BASE)
- #define CUETIP 10
- #define MAXCUELENGTH 80
-
- #define CLOCKWISE 1
- #define ANTICLOCKWISE 2
- #define SMALL 1
- #define LARGE 2
- #define UP 1
- #define DOWN 2
- #define NOHIT -1
- #define ON TRUE
- #define OFF FALSE
- #define HIT 3
- #define UPDATE 3
- #define ICON 2
- #define VIEW 1
- #define NOREFRESH 2
-
- #define RACKED 1
- #define BROKEN 0
- #define OPEN 2
- #define SPREAD 3
-
- #undef SINGLE
-
- enum icons { PLYR1,PLYR2,PRACTICE,DEMO,PLAY,QUIT,_BAIZE,_BALL1,_BALL2,
- SINGLE,BEST3,BEST5,UNLIMITED,STRIP,BALL10,BALL16,
- OPPONENTBASE,ICON17,ICON18,ICON19,STRIPPERBASE };
-
- enum args { GAMETYPE,GAMELENGTH,BAIZE,BALL1,BALL2,BALLCOUNT,OPPONENT,STRIPPER };
-
- #define HUMANPLYR 0
- #define COMPLYR 1
-
- #define FRICTION (BASESP / 300)
- #define SPINFRICTION 3
- #define SPEEDINC (BASESP / 16)
- #define MAXSPEED (BASESP * 4)
- #define MINSPEED (BASESP / 4)
-
- #define ESC 69
- #define RETURN 68
- #define SPACE 64
- #define HELP 95
- #define LCSR 79
- #define RCSR 78
- #define UCSR 76
- #define DCSR 77
- #define F1 80
- #define F2 81
- #define F3 82
- #define F4 83
- #define F5 84
- #define F6 85
- #define F7 86
- #define F8 87
- #define F9 88
- #define F10 89
-
- #define FLASH 2
-
- #define JOYFIRE 0xbfe001
- #define LMOUSE 1
- #define RMOUSE 2
-
- #define MEMSIZE 7000
-
- void DoControl(void);
- void DrawCue(short);
- void ChangePower();
- short ChangeSpin(void);
- void DrawCross(short);
- void MoveCue(short,short);
- void DoAssigns(void);
- void SetUpTable(void);
- void DoOptions(void);
- short GetInput(void);
- char UpdateBallPos(void);
- void WaitBeam(short);
- short CheckPotted(short);
- void CheckBounce(short);
- void CheckCollision(void);
- void MakeCollision(short,short);
- void DrawBall(short,short);
- void DrawBallDirect(short,short,short);
- short FindAngle(WORD,WORD,WORD);
- void SuperImpose(struct RastPort *,short,short,struct RastPort *,
- short,short,short,short,short,short);
- void WriteMessage(short,short,short,short);
- void ScrubMessage(void);
- void PlayShot(void);
- void CheckResult(void);
- void CheckWhitePotted(void);
- short TouchingBall(short);
- void PlayComputerShot(void);
- void CheckBallDrag(void);
- void CopyBalls(struct ballstruct*,struct ballstruct*);
- void CopyPlayer(short,short);
- WORD QuickRoot(long);
- short GetMouse(void);
- char LoadIFF(struct IFFGraphic *,struct Screen *,char);
- char ClickDelay(short);
- void CueJumpAnim(void);
- void CheckAngle(short *);
- UWORD Rand(UWORD);
- long MyRead(struct FileHandle *,long *,long);
- char OpenIt(void);
- void CloseIt(void);
-
- APTR GetDeviceBlock(ULONG);
- void FreeDeviceBlock(struct IOAudio *,BYTE);
- void Audio_PerVol(struct IOAudio *,UWORD,UWORD);
- void Audio_Write(struct IOAudio *,UBYTE *,UWORD);
- void PlaySound(struct audioinfostruct *,short);
-
- /******************* Graphics defines ******************/
- struct NewScreen ns =
- {
- 0,0, /* Left edge, top */
- 320,256, /* Width, height */
- 5, /* Depth (32 colours) */
- 0,1, /* Detail, block pens */
- 0, /* Modes for ViewPort */
- CUSTOMSCREEN | SCREENQUIET,
- /* Screen type */
- NULL, /* Text attributes */
- NULL, /* Title */
- NULL, /* Gadget list */
- NULL /* Custom bitmap pointer */
- };
-
- struct NewWindow nw =
- {
- 0,0, /* Starting corner */
- 320,256, /* Width, height */
- 0,1, /* detail, block pens */
- RAWKEY, /* IDCMP flags */
- BORDERLESS | ACTIVATE | RMBTRAP,
- /* Window flags */
- NULL, /* Pointer to first gadget */
- NULL, /* Pointer to checkmark */
- NULL, /* title */
- NULL, /* screen pointer (don't know yet) */
- NULL, /* bitmap pointer */
- 0,0,0,0, /* window not sized */
- CUSTOMSCREEN /* type of screen */
- };
-
- /* Extra padding for use with tempmask. Must set ballmask to point to */
- /* first 'real' byte (8) at start of program */
-
- USHORT chip crossmask[5] = { 0x2000,0x2000,0xd800,0x2000,0x2000 };
-
- USHORT chip mask[37] = { 0,0,0,0,0,0,0,0,0,0,0,0,
- 0x3e0,0xff8,0x1ffc,0x1ffc,0x3ffe,0x3ffe,
- 0x3ffe,0x3ffe,0x3ffe,0x1ffc,0x1ffc,0xff8,0x3e0,
- 0,0,0,0,0,0,0,0,0,0,0,0 };
-
- USHORT chip mask2[10] = { 0x3e0,0xff0,0xff8,0x1ff8,0x1ff8,0x1ff8,
- 0x1ff0,0x1ff0,0xfe0,0x780 };
-
- USHORT chip hybridmask[13] =
- { 0x3e0,0xff8,0x7fc,0x3fc,0x1fe,0xfe,0x7e,0x3e,0x1e,0xc,0x4,0,0 };
-
- USHORT chip hybridmask2[10] =
- { 0x3e0,0x7f0,0x3f8,0x1f8,0x0f8,0x078,0x030,0x010,0,0 };
-
- USHORT chip miniball[8] =
- { 0x3c00,0x7e00,0xff00,0xff00,0xff00,0xff00,0x7e00,0x3c00 };
-
- USHORT *ballmask = &mask[12];
- USHORT *ballmask2 = mask2;
- USHORT chip tempmask[256];
-
- USHORT chip buffer[20];
-
- /********************* System defines ************************/
- struct Screen *s,*s2;
- struct Window *w,*w2;
- struct RastPort *rp,*rp2,bufrp;
- struct BitMap *bm,*bm2,bufbm;
- struct ViewPort *vp;
- struct ColorMap *cm;
- struct IntuiMessage *msg;
- struct FileHandle *fh;
- struct Preferences prefs;
-
- UWORD *colorpalette;
-
- char *bp0,*bp1,*bp2,*bp3,*bp4;
-
- extern UWORD chip pointeron[24];
- extern UWORD chip pointeroff[8];
-
- long oldkeydelay,oldkeyspeed;
-
- /******************* Audio Defines ******************/
-
- #define SAMPLES 8
- #define AM2 106 /* Audio Master II info size */
- #define BUFWAVELEN 100
-
- enum sound { COLLIDE,STRIKE,BOUNCE,POTTED,CHEER,LONGCHEER,CHANT,CRASH };
-
- #define AUDIO_LEN (sizeof(struct IOAudio))
- #define PRECIDENCE 127
- #define CLOSE_DEVICE 1
-
- #define BUFFER 0
- #define RESET 1
-
- struct IOAudio *audio[4];
- char Channel_Map[] = { 1,2,4,8 },*bufwave;
-
- struct audioinfostruct
- {
- struct IOAudio *audio;
- char *wave,bufstate,channel,flag;
- long wavelen;
- short volume,period;
- char filename[30];
- };
-
- struct audioinfostruct audioinfo[SAMPLES] = {
- { 0,0,0,0,BUFFER,702-AM2,0,320,"FNPAUDIO:collide.sam" },
- { 0,0,0,1,BUFFER,544-AM2,0,600,"FNPAUDIO:strike.sam" },
- { 0,0,0,2,RESET,448-AM2,0,640,"FNPAUDIO:bounce.sam" },
- { 0,0,0,3,BUFFER,1386-AM2,0,315,"FNPAUDIO:pot.sam" },
- { 0,0,0,2,RESET,19708-AM2,0,550,"FNPAUDIO:cheer.sam" },
- { 0,0,0,2,RESET,36682-AM2,0,550,"FNPAUDIO:cheer2.sam" },
- { 0,0,0,2,RESET,20432-AM2,0,536,"FNPAUDIO:chant.sam" },
- { 0,0,0,2,RESET,18960-AM2,0,286,"FNPAUDIO:crash.sam" }};
-
- /********************* Gameplay defines **********************/
-
- UWORD rgb[32];
- UWORD rgb2[32] = {
- 0x000,0xfb9,0xd86,0x593,0x030,0x400,0x610,0x820,
- 0x150,0xfc0,0xf00,0x382,0xfff,0xfff,0xfcc,0x270,
- 0x444,0xb8b,0x000,0xfff,0xf83,0xfc7,0x000,0x000,
- 0x000,0xfff,0x888,0x000,0x9cf,0x000,0x000,0x000 };
-
- enum col {
- _back,_leather,_dkleather,_ltbaize,_dkbaize,_dkwalnut,_walnut,_ltwalnut,
- _baize,_yellow,_red,_ltbaize2,_white,_highyel,_highred,_ltbaize3,
- _cross,_ptr17,_ptr18,_ptr19,_cuecol,_ltcuecol,_22,_23,
- _black,_text1,_text2 };
-
- enum balltype { white,black,yellow,red,anyball,baize };
- char ballpalette[] = { _white,_black,_yellow,_red, 0,_baize };
-
- char ball15colour[16] = {
- white,yellow,red,yellow,yellow,black,red,red,
- yellow,red,yellow,yellow,red,yellow,red,red };
-
- char ball9colour[10] = {
- white,red,red,red,red,black,red,red,red,red };
-
- char ballplanes[] = { 4,16,1,2, 0,23 };
-
- struct ballstruct
- {
- enum balltype colour;
- char potted,justpotted,hasmoved,lasthit,olddx,olddy;
- USHORT x,y;
- short speed,angle,scrnx,scrny,oldscrnx,oldscrny;
- };
- struct ballstruct ball[16],tempball[16];
-
- struct pixelsavestruct
- {
- char col;
- short x,y;
- };
- struct pixelsavestruct pixelsave[32];
-
- struct blitdatstruct
- {
- short x,y,dx,dy;
- };
- struct blitdatstruct blitdat,blitdat2;
-
- char *quickarcsin;
- short *memblock,*quicksin,*quickcos,
- cueangle=270,cuespeed=MINSPEED,powerdirn=UP,
- spinx,spiny,swerve,swervetotal,
- gametype,gamelength,stripper,opponent,
- defaultdemo,enableoptions=TRUE,flipoffer,
- cloth,cueline=ON,firsthit,dotspacing=8,cheer=ON,
- plyrbreak,turn,comp1,comp2,
- balls=16,dragcheat,cheatangle=-1,cheatball,
- foul,endofgame,quitgame,winner,matches,coin,packstate,newbreak;
-
- USHORT seed; /* random element */
-
- USHORT pocketx[6] = { (TABLELENGTH-BALLRADIUS),(TABLELENGTH-BALLRADIUS),
- (TABLELENGTH/2),(TABLELENGTH/2),BALLRADIUS,BALLRADIUS };
-
- USHORT pockety[6] = { (TABLEWIDTH-BALLRADIUS),BALLRADIUS,
- (TABLEWIDTH-BALLRADIUS),BALLRADIUS,(TABLEWIDTH-BALLRADIUS),BALLRADIUS };
-
- char angleused[360];
-
- char joydelay;
-
- extern struct Custom far custom;
-
- /********* Loader stuff *************/
-
- extern struct IFFGraphic
- {
- char FileName[30]; /* Name of IFF file */
- BYTE ReqDepth; /* How many bitplanes wish to be Displayed */
- USHORT *RGB; /* RGB colour values, filled by LoadIFF */
- short Width; /* Width of graphic, filled by LoadIFF */
- short Height; /* Height of graphic, filled by LoadIFF */
- BYTE Depth; /* Depth of graphic, filled by LoadIFF */
- };
-
- extern char arg[8],bufarg[8],demoarg[8];
-
- struct IFFGraphic
- tableIFF = { "FNPGRAPHICS:table.img",5,NULL },
- offerIFF = { "FNPGRAPHICS:offer.img",5,rgb },
- offer2IFF = { "FNPGRAPHICS:offer2.img",5,rgb };
-
- UWORD RGBbaize[] = {
- 0x593,0x030,0x150,0x382,0x270, /* green */
- 0x368,0x023,0x034,0x156,0x145, /* blue */
- 0x965,0x421,0x632,0x854,0x743, /* brown */
- 0x777,0x333,0x444,0x666,0x555 }; /* grey */
-
- UWORD RGBball[] = { 0xf00,0xf40,0xfa0,0x390,0x05f,0x608,0xf55 };
-
- UWORD RGBroom[16];
-
- /********** Strip stuff *****************/
-
- struct IFFGraphic roomIFF = { "FNPGRAPHICS:room.img",5,RGBroom };
-
- struct IFFGraphic stripimageIFF[4] = {
- { "FNPGRAPHICS:claire_sally.img",5,rgb },
- { "FNPGRAPHICS:michael.img",5,rgb },
- { "FNPGRAPHICS:claire_sally.img",5,rgb },
- { "FNPGRAPHICS:josh.img",5,rgb }};
-
- struct IFFGraphic striptextIFF[4] = {
- { "FNPGRAPHICS:quotes.img",5,rgb },
- { "FNPGRAPHICS:quotes.img",5,rgb },
- { "FNPGRAPHICS:quotes.img",5,rgb },
- { "FNPGRAPHICS:quotes2.img",5,rgb }};
-
- struct stripstruct
- {
- short imgx1[4],imgy1[4],imgdx[4],imgdy[4],imgx2[4],imgy2[4],
- textx[5],texty[5],textdx[5],textdy[5];
- };
-
- struct stripstruct stripinfo[4] = {
- { 192,129,65,0, 0,0,0,0, 60,60,60,60,
- 139,139,139,139, 19,19,19,19, 68,68,68,68,
- 0,113,89,0,207, 0,0,39,39,39, 112,200,117,88,88, 32,39,39,32,32 },
-
- { 195,128,61,0, 0,0,0,0, 65,65,65,58,
- 149,149,149,149, 11,11,11,11, 57,57,57,57,
- 135,0,0,237,148, 80,172,211,153,153, 110,147,118,82,88, 32,39,41,53,32 },
-
- { 211,140,70,0, 139,139,139,139, 67,67,67,67,
- 112,112,112,112, 27,27,27,27, 90,90,90,90,
- 0,135,0,224,245, 133,113,80,113,80, 117,88,133,81,75, 39,32,53,39,32 },
-
- { 170,108,57,0, 0,0,0,0, 56,56,50,50,
- 171,171,161,161, 17,28,23,23, 50,51,50,50,
- 0,0,171,0,139, 60,0,0,106,60, 139,171,149,131,113, 46,60,53,46,53 }};
-
- /******* Message stuff *****************/
-
- #define NEW 0
- #define FOLLOW 1
-
- enum msg { MSG_PLACECUEBALL,MSG_FOUL,MSG_WINS,MSG_MICHAEL,MSG_JOSH,
- MSG_CLAIRE,MSG_SALLY,MSG_PLAYER1,MSG_PLAYER2,MSG_QUITTING,
- MSG_VS,MSG_GAME,MSG_OF,MSG_0,MSG_1,MSG_2,MSG_3,MSG_4,MSG_5,
- MSG_GOODSHOT,MSG_SHOTCANCELLED,MSG_BADLUCK,MSG_WELLDONE,
- MSG_QUITGAME,MSG_ISTHECHAMP,MSG_OOOPS };
-
- short cursor;
-
- struct messagestruct { short x1,y1,x2,y2; };
- struct messagestruct message[] = {
- { 0,0,122,13 }, { 123,0,174,13 }, { 175,0,214,13 }, { 215,0,275,13 },
- { 276,0,313,13 },
-
- { 0,14,44,31 }, { 45,14,82,31 }, { 83,14,144,31 },
- { 145,14,208,31 }, { 209,14,284,31 }, { 285,14,301,31 },
-
- { 0,32,44,45 }, { 45,32,60,45 }, { 240,60,253,77 }, { 61,32,64,45 },
- { 65,32,72,45 }, { 73,32,80,45 }, { 81,32,89,45 }, { 90,32,97,45 },
- { 98,32,196,45 }, { 197,32,317,45 },
-
- { 0,46,74,59 }, { 75,46,160,59 },
-
- { 0,60,127,77 }, { 128,60,239,77 }, { 240,60,299,77 }};
-
- /************ Player stuff **************/
-
- struct playerstruct
- {
- enum balltype colour;
- char goes,wins;
- char nametag;
- short maxpower;
- char cuepulls,skill;
- };
-
- struct playerstruct player[8] = {
- { 0,0,0,0,MAXSPEED,0,0 }, /* Filled 1 */
- { 0,0,0,0,MAXSPEED,0,0 }, /* Filled 2 */
-
- { 0,0,0,MSG_PLAYER1,MAXSPEED,1,3 }, /* Player 1 */
- { 0,0,0,MSG_PLAYER2,MAXSPEED,1,3 }, /* Player 2 */
- { 0,0,0,MSG_CLAIRE,MAXSPEED,2,0 }, /* Claire */
- { 0,0,0,MSG_MICHAEL,MAXSPEED+MAXSPEED/2,0,2 }, /* Mike */
- { 0,0,0,MSG_SALLY,MAXSPEED-MAXSPEED/4,1,3 }, /* Sally */
- { 0,0,0,MSG_JOSH,MAXSPEED,3,3 }}; /* Josh */
-
- /**********************/
- main()
- {
- short i,match;
-
- if (!OpenIt()) { CloseIt(); return; }
- DoAssigns();
- if (Loader(1)) do
- {
- coin=-1; DoOptions();
- switch(gamelength)
- {
- case BEST3:
- case BEST5:
- for(match=0; match<matches; match++)
- {
- WriteMessage(MSG_GAME,5,5,NEW);
- WriteMessage(MSG_1+match,0,5,FOLLOW);
- WriteMessage(MSG_OF,0,5,FOLLOW);
- WriteMessage((MSG_1-1)+matches,0,5,FOLLOW);
- SetUpTable(); Delay(100); DoControl();
- if (player[0].wins>matches/2 ||
- player[1].wins>matches/2 ||
- quitgame) break;
- WriteMessage(player[1-winner].nametag,5,5,NEW);
- WriteMessage(MSG_0+player[1-winner].wins,15,5,FOLLOW);
- Delay(65);
- WriteMessage(player[winner].nametag,5,5,NEW);
- WriteMessage(MSG_0+player[winner].wins,15,5,FOLLOW);
- Delay(65);
- }
- if (!quitgame)
- {
- FadeScreen(s,DOWN); SetRast(rp,_back);
- WriteMessage(player[winner].nametag,60,80,NEW);
- WriteMessage(MSG_ISTHECHAMP,0,80,FOLLOW);
- FadeScreen(s,UP); ClickDelay(400);
- } break;
- case SINGLE:
- SetUpTable(); DoControl(); break;
- case UNLIMITED:
- do
- { SetUpTable(); DoControl(); } while (!quitgame);
- break;
- case STRIP:
- {
- short image=0,text=1;
-
- for(match=0; match<4;
- match++,image++,text++)
- {
- WriteMessage(MSG_GAME,5,5,NEW);
- WriteMessage(MSG_1+match,0,5,FOLLOW);
- WriteMessage(MSG_OF,0,5,FOLLOW);
- WriteMessage(MSG_4,0,5,FOLLOW);
- SetUpTable(); Delay(100); DoControl();
- if (quitgame) break;
- if (winner==COMPLYR) { text=0; image=0; }
-
- FadeScreen(s,DOWN);
-
- LoadIFF(&striptextIFF[stripper],s,NOREFRESH);
-
- BltBitMap(bm,stripinfo[stripper].textx[text],
- stripinfo[stripper].texty[text],&bufbm,0,85,
- stripinfo[stripper].textdx[text],
- stripinfo[stripper].textdy[text],0xc0,31,buffer);
-
- LoadIFF(&stripimageIFF[stripper],s,NOREFRESH);
-
- BltBitMap(bm,stripinfo[stripper].imgx1[image],
- stripinfo[stripper].imgy1[image],&bufbm,250,0,
- stripinfo[stripper].imgdx[image],
- stripinfo[stripper].imgdy[image],0xc0,31,buffer);
-
- for (i=0; i<16; i++)
- { rgb[16+i] = rgb[i]; rgb[i] = RGBroom[i]; }
-
- BltBitMap(bm2,0,0,bm,0,0,320,256,0xc0,31,buffer);
-
- SuperImpose(&bufrp,0,85,rp,101,28,
- stripinfo[stripper].textdx[text],
- stripinfo[stripper].textdy[text],0,7);
-
- SuperImpose(&bufrp,250,0,rp,
- stripinfo[stripper].imgx2[image],
- stripinfo[stripper].imgy2[image],
- stripinfo[stripper].imgdx[image],
- stripinfo[stripper].imgdy[image],0,16);
-
- FadeScreen(s,UP);
-
- if (match==3) PlaySound(&audioinfo[LONGCHEER],64);
- ClickDelay(600);
- if (match==3 || winner==COMPLYR) break;
- arg[OPPONENT]++; DoOptions();
- }
- break;
- }
- }
- /* enableoptions = FALSE;
- if (flipoffer = 1-flipoffer)
- {
- short flash=0xf00,dirn=-0x100,count=0;
-
- LoadIFF(&offer2IFF,s,VIEW);
- while (!(GetMouse()) && ++count < 1500)
- {
- flash+=dirn;
- if (flash==0xf00 || flash==0x400) dirn = -dirn;
- colorpalette[1] = flash;
- MakeScreen(s); RethinkDisplay();
- Delay(2);
- }
- }
- else { LoadIFF(&offerIFF,s,VIEW); ClickDelay(1500); }
- */
- } while (Loader(0));
- CloseIt();
- }
- /**********************/
- void CueJumpAnim()
- {
- short y=125,x=180,oldx,oldy,crash=FALSE,
- forcex=quicksin[ball[CUE].angle] * 7 / BASE,
- forcey=-12,bounce=0,onscreen=TRUE;
-
- ball[CUE].potted = TRUE; ball[CUE].justpotted = TRUE;
- ball[CUE].scrnx = ball[CUE].oldscrnx;
- ball[CUE].scrny = ball[CUE].oldscrny;
- DrawBall(CUE,OFF);
-
- if (forcex > 4) { forcey = -16; crash = TRUE; }
-
- ScreenToFront(s2); ActivateWindow(w2);
- SetAPen(rp2,8); PlaySound(&audioinfo[POTTED],64);
-
- while(1)
- {
- if (onscreen)
- {
- BltBitMap(bm2,x,y,&bufbm,0,100,8,8,0xc0,31,buffer);
- BltPattern(rp2,miniball,x,y,x+7,y+7,2);
- }
- else Delay(1);
- oldx = x; oldy = y;
- y+=forcey++/2; x+=forcex;
- if (y >= 220+bounce*4)
- {
- y=220+bounce*2; forcey=-forcey/4; bounce++;
- PlaySound(&audioinfo[BOUNCE],32 + 32/bounce);
- }
- if (bounce==3) Delay(75);
- if (onscreen)
- {
- WaitBeam(oldy+10);
- BltBitMap(&bufbm,0,100,bm2,oldx,oldy,8,8,0xc0,31,buffer);
- }
- if (bounce==3) break;
- if (x < 0 || x > 310)
- {
- if (crash) break;
- onscreen=FALSE;
- }
- }
- if (crash)
- {
- PlaySound(&audioinfo[CRASH],64); Delay(100);
- PlaySound(&audioinfo[CHEER],64);
- }
- WriteMessage(MSG_OOOPS,30,5,NEW);
- ScreenToFront(s); ActivateWindow(w);
- }
- /*************************/
- void DoControl()
- {
- short input,i,key=0;
-
- if (gametype==PRACTICE || dragcheat) SetPointer(w,pointeron,11,11,0,0);
- WriteMessage(player[turn].nametag,5,5,NEW); GetInput();
- quitgame = FALSE; endofgame = FALSE;
-
- do
- {
- input = GetInput();
-
- if (gametype==DEMO || (gametype==PLYR1 && turn==COMPLYR))
- {
- if (input==ESC) quitgame=TRUE;
- else PlayComputerShot();
- }
- else switch(input)
- {
- case ESC: quitgame=TRUE; break;
-
- case RETURN:
- {
- BOOL play=TRUE;
-
- if (ChangeSpin()==FALSE) play=FALSE;
- else do { input = GetInput(); ChangePower(); }
- while (!(input==RETURN || input==ESC));
-
- if (input==ESC) play=FALSE;
- if (play) PlayShot();
- else
- {
- WriteMessage(MSG_SHOTCANCELLED,5,5,NEW);
- cuespeed=MINSPEED; Delay(50);
- WriteMessage(player[turn].nametag,5,5,NEW);
- }
- } break;
-
- case LCSR: MoveCue(CLOCKWISE,SMALL); break;
- case RCSR: MoveCue(ANTICLOCKWISE,SMALL); break;
- case UCSR: MoveCue(CLOCKWISE,LARGE); break;
- case DCSR: MoveCue(ANTICLOCKWISE,LARGE); break;
-
- case SPACE: do ChangePower(); while (cuespeed < (MAXSPEED/2));
- PlayShot(); break;
-
- case F1: DrawCue(OFF);
- if ((dotspacing+=2) > 12) dotspacing=4;
- DrawCue(ON); break;
-
- case F2: player[2].cuepulls = 1-player[2].cuepulls;
- player[0].cuepulls = player[2].cuepulls;
- player[3].cuepulls = 1-player[3].cuepulls;
- player[1].cuepulls = player[3].cuepulls;
- cuespeed=MAXSPEED; DrawCue(OFF);
- DrawCue(HIT); DrawCue(ON); cuespeed=MINSPEED; break;
-
- case F3: DrawCue(OFF); cueline=(1-cueline); DrawCue(ON); break;
- case F4: /* cheer toggle */
- if (cheer = 1-cheer) PlaySound(&audioinfo[CHEER],64);
- break;
-
- case F5: /* smash balls */
- if (gametype==PRACTICE || dragcheat)
- {
- for (i=0; i<balls; i++)
- {
- ball[i].angle = Rand(360);
- ball[i].speed = MAXSPEED;
- }
- cuespeed = MAXSPEED; PlayShot();
- } break;
-
- case F6: if (gametype==PRACTICE || dragcheat)
- {
- DrawCue(OFF); SetUpTable();
- WriteMessage(player[turn].nametag,5,5,NEW);
- } break;
-
- case 37: /* "hogan" win game cheat!!! */ key = 10; break;
- case 24: if (key==10) key = 20; break;
- case 36: if (key==20) key = 30; break;
- case 32: if (key==30) key = 40; break;
- case 54: if (key==40) { endofgame=TRUE; winner=HUMANPLYR; }
- break;
-
- case 25: /* "pixie" dragball cheat!!! */ key = 1; break;
- case 23: if (key==1) key = 2; if (key==3) key = 4; break;
- case 50: if (key==2) key = 3; break;
- case 18: if (key==4)
- {
- if (dragcheat=1-dragcheat)
- SetPointer(w,pointeron,11,11,0,0);
- else SetPointer(w,pointeroff,1,1,0,0);
- } break;
-
- case HELP: if (gametype==PRACTICE || dragcheat)
- PlayComputerShot(); break;
- }
- if (quitgame)
- {
- if (gametype==DEMO)
- {
- if (defaultdemo) for(i=0; i<8; i++) arg[i] = bufarg[i];
- defaultdemo=FALSE;
- WriteMessage(MSG_QUITTING,5,5,NEW); Delay(50);
- }
- else
- {
- WriteMessage(MSG_QUITGAME,5,5,NEW);
- do input = GetInput();
- while (input!=21 && input!=54);
- if (input==54)
- {
- WriteMessage(player[turn].nametag,5,5,NEW);
- quitgame=FALSE;
- }
- else { WriteMessage(MSG_QUITTING,5,5,NEW); Delay(50); }
- }
- }
- if (endofgame && gametype!=PRACTICE)
- {
-
- player[winner].wins++;
- if (gametype==PLYR1)
- {
- if (winner==HUMANPLYR)
- {
- WriteMessage(MSG_WELLDONE,5,5,NEW);
- if (cheer) PlaySound(&audioinfo[LONGCHEER],64);
- }
- else WriteMessage(MSG_BADLUCK,5,5,NEW);
- Delay(75);
- }
- else if (cheer) PlaySound(&audioinfo[LONGCHEER],64);
- WriteMessage(player[winner].nametag,5,5,NEW);
- WriteMessage(MSG_WINS,0,5,FOLLOW);
- Delay(100); ScrubMessage();
- if (defaultdemo) for(i=0; i<8; i++) arg[i] = bufarg[i];
- defaultdemo=FALSE;
- }
- if (gametype==PRACTICE || dragcheat) CheckBallDrag();
-
- } while(!quitgame && !endofgame);
- DrawCue(OFF); SetPointer(w,pointeroff,1,1,0,0);
- }
- /**********************/
- void DrawCue(status)
- short status;
- {
- short i,j,x1,y1,x2,y2,dx,dy,dirnlen=0,cuelen=MAXCUELENGTH,
- viewline=cueline;
-
- if (gametype==DEMO || (gametype==PLYR1 && turn==COMPLYR)) viewline=0;
-
- rp->Mask = 31;
- if (status == ON)
- {
- x1 = X1CORNER + (ball[CUE].x + CUETIP * quicksin[cueangle]
- * quicksin[90+spinx/12]/BASE
- - spinx/100 * quickcos[cueangle]) / BASE;
-
- y1 = (Y2CORNER-1) - (ball[CUE].y + CUETIP*quickcos[cueangle]
- * quicksin[90+spinx/12]/BASE
- + spinx/100 * quicksin[cueangle]) / BASE;
- do
- {
- x2 = x1 + cuelen * quicksin[cueangle]/BASE;
- y2 = y1 - cuelen * quickcos[cueangle]/BASE;
- cuelen--;
-
- } while (x2 < 1 || x2 > 318 || y2 < 33 || y2 > 254);
-
- blitdat.x = (x1 < x2)? x1-1:x2-1;
- blitdat.y = (y1 < y2)? y1-1:y2-1;
- blitdat.dx = abs(x1-x2)+3;
- blitdat.dy = abs(y1-y2)+3;
-
- BltBitMap(bm,blitdat.x,blitdat.y,&bufbm,
- 0,0,blitdat.dx,blitdat.dy,0xc0,31,buffer);
-
- SetAPen(rp,_cuecol);
- for (dx=-1; dx<2; dx++) for (dy=-1; dy<2; dy++)
- { Move(rp,x1,y1); Draw(rp,x2+dx,y2+dy); }
-
- SetAPen(rp,_ltcuecol); Move(rp,x1,y1); Draw(rp,x2,y2);
-
- SetAPen(rp,_black); WritePixel(rp,x1,y1);
-
- x1 = X1CORNER + ball[CUE].x/BASE - CUETIP*quicksin[cueangle]/BASE;
- y1 = (Y2CORNER-1) - ball[CUE].y/BASE + CUETIP*quickcos[cueangle]/BASE;
-
- if (viewline)
- {
- SetAPen(rp,_white);
-
- for (i=0; i<32; i++,dirnlen+=dotspacing)
- {
- x2 = x1 - dirnlen * quicksin[cueangle]/BASE;
- y2 = y1 + dirnlen * quickcos[cueangle]/BASE;
-
- for (j=0; j<2; j++)
- {
- if (y2 < (Y1CORNER+7)) y2 += ((Y1CORNER+7)-y2)<<1;
- if (y2 > (Y2CORNER-7)) y2 -= (y2-(Y2CORNER-7))<<1;
- if (y2 < (Y1CORNER+7)) y2 += ((Y1CORNER+7)-y2)<<1;
- if (x2 < (X1CORNER+7)) x2 += ((X1CORNER+7)-x2)<<1;
- if (x2 > (X2CORNER-7)) x2 -= (x2-(X2CORNER-7))<<1;
- if (x2 < (X1CORNER+7)) x2 += ((X1CORNER+7)-x2)<<1;
- }
- pixelsave[i].col = ReadPixel(rp,x2,y2);
- pixelsave[i].x = x2;
- pixelsave[i].y = y2;
- }
- for (i=0; i<32; i++)
- WritePixel(rp,pixelsave[i].x,pixelsave[i].y);
- }
- }
- else if (status==OFF)
- {
- if (viewline)
- {
- WaitBOVP(vp);
- for (i=31; i>=0; i--)
- {
- SetAPen(rp,pixelsave[i].col);
- WritePixel(rp,pixelsave[i].x,pixelsave[i].y);
- }
- }
- WaitBeam(blitdat.y+blitdat.dy);
- BltBitMap(&bufbm,0,0,bm,
- blitdat.x,blitdat.y,blitdat.dx,blitdat.dy,0xc0,31,buffer);
- }
- else if (status==HIT)
- {
- char firstrun = 0,stage;
- short offset;
-
- for (stage=0; stage<player[turn].cuepulls+1; stage++)
- for (i=0; i<=180; i+=15)
- {
- if (stage==player[turn].cuepulls)
- offset = quicksin[i]*60*cuespeed/MAXSPEED/BASE;
-
- else offset = (BASE-quickcos[i+i])
- *15*cuespeed/MAXSPEED/BASE;
-
- cuelen = MAXCUELENGTH;
-
- x1 = X1CORNER + (ball[CUE].x + CUETIP * quicksin[cueangle]
- * quicksin[90+spinx/12]/BASE
- - spinx/100 * quickcos[cueangle]
- + offset*quicksin[cueangle]) / BASE;
-
- y1 = (Y2CORNER-1) - (ball[CUE].y + CUETIP*quickcos[cueangle]
- * quicksin[90+spinx/12]/BASE
- + spinx/100 * quicksin[cueangle]
- + offset*quickcos[cueangle]) / BASE;
-
- if (x1 < 1 || x1 > 318 || y1 < 33 || y1 > 254) continue;
-
- do
- {
- x2 = x1 + cuelen * quicksin[cueangle]/BASE;
- y2 = y1 - cuelen * quickcos[cueangle]/BASE;
- cuelen--;
-
- } while (x2 < 1 || x2 > 318 || y2 < 33 || y2 > 254);
-
- if (!firstrun)
- {
- Delay(1); WaitBeam(blitdat.y+blitdat.dy);
- BltBitMap(&bufbm,0,0,bm,blitdat.x,blitdat.y,
- blitdat.dx,blitdat.dy,0xc0,31,buffer);
- }
-
- blitdat.x = (x1 < x2)? x1-1:x2-1;
- blitdat.y = (y1 < y2)? y1-1:y2-1;
- blitdat.dx = abs(x1-x2)+3;
- blitdat.dy = abs(y1-y2)+3;
-
- BltBitMap(bm,blitdat.x,blitdat.y,&bufbm,
- 0,0,blitdat.dx,blitdat.dy,0xc0,31,buffer);
-
- SetAPen(rp,_cuecol);
- for (dx=-1; dx<2; dx++) for (dy=-1; dy<2; dy++)
- { Move(rp,x1,y1); Draw(rp,x2+dx,y2+dy); }
-
- SetAPen(rp,_ltcuecol); Move(rp,x1,y1); Draw(rp,x2,y2);
- SetAPen(rp,_black); WritePixel(rp,x1,y1);
- firstrun = 0;
- }
- WaitBeam(blitdat.y+blitdat.dy);
- BltBitMap(&bufbm,0,0,bm,blitdat.x,blitdat.y,
- blitdat.dx,blitdat.dy,0xc0,31,buffer);
- }
- }
- /***********************/
- void MakeCollision(i,j)
- short i,j;
- {
- short dx,dy,volume,theta,dxi,dxj,dyi,dyj,
- reldx,reldy,relspeed,relangle,
- passx,passy,transfer,intersect,jump=FALSE;
-
- dx = ball[j].x - ball[i].x;
- dy = ball[j].y - ball[i].y;
- intersect = BALLDIAMETER - QuickRoot(dx*dx + dy*dy);
-
- if (i==CUE && ball[CUE].speed > (MAXSPEED*3/4) &&
- spiny < -600 && !(Rand(2))) { jump=TRUE; CueJumpAnim(); }
-
- /* Find pure offsets */
- dxi = ball[i].speed * quicksin[ball[i].angle] / BASE;
- dyi = ball[i].speed * quickcos[ball[i].angle] / BASE;
- dxj = ball[j].speed * quicksin[ball[j].angle] / BASE;
- dyj = ball[j].speed * quickcos[ball[j].angle] / BASE;
-
- /* Ball i relative offsets - makes ball j static */
- reldx = dxi - dxj;
- reldy = dyi - dyj;
-
- relspeed = QuickRoot(reldx*reldx + reldy*reldy);
-
- /* Reposition balls so that they collide at surface */
- if (relspeed > BASE && packstate==SPREAD)
- {
- dx = (ball[j].x - dxj * intersect / relspeed) -
- (ball[i].x - dxi * intersect / relspeed);
-
- dy = (ball[j].y - dyj * intersect / relspeed) -
- (ball[i].y - dyi * intersect / relspeed);
- }
- theta = FindAngle(dx,dy,BALLDIAMETER);
- /* Common angle between balls */
-
- relangle = FindAngle(reldx,reldy,relspeed);
- /* Find angle of relative velocity */
-
- /* Power transfer from one ball to another */
- transfer = abs(quickcos[abs(theta - relangle)])*relspeed*3/BASE/4;
-
- passx = transfer * quicksin[theta] / BASE;
- passy = transfer * quickcos[theta] / BASE;
-
- if (i==CUE && spiny)
- {
- dxi += dxi * spiny / 800 *
- abs(quickcos[abs(theta - relangle)]) / BASE;
- dyi += dyi * spiny / 800 *
- abs(quickcos[abs(theta - relangle)]) / BASE;
- spiny=0; swerve=0;
- }
-
- dxj += passx; dyj += passy;
- dxi -= passx; dyi -= passy;
-
- ball[i].speed = QuickRoot(dxi*dxi + dyi*dyi);
- if (ball[i].speed > MAXSPEED) ball[i].speed = MAXSPEED;
- else if (ball[i].speed < 6) ball[i].speed = 6;
- if (ball[i].speed) ball[i].angle = FindAngle(dxi,dyi,ball[i].speed);
-
- ball[j].speed = QuickRoot(dxj*dxj + dyj*dyj);
- if (ball[j].speed > MAXSPEED) ball[j].speed = MAXSPEED;
- else if (ball[j].speed < 6) ball[j].speed = 6;
- if (ball[j].speed) ball[j].angle = FindAngle(dxj,dyj,ball[j].speed);
-
- if (i==CUE && spinx)
- {
- ball[CUE].angle-=spinx/25;
- CheckAngle(&ball[CUE].angle);
- spinx=0; swerve=0;
- }
- ball[i].lasthit = j; ball[j].lasthit = i;
-
- if (cheatangle!=-1 && j==cheatball)
- {
- ball[j].angle = cheatangle;
- if (ball[j].speed < ball[CUE].speed>>2)
- ball[j].speed = ball[CUE].speed>>2;
- }
- cheatangle=-1;
-
- if ((packstate!=BROKEN || !newbreak) && !jump)
- {
- /* Prevent multiple collisions on break */
- if ((volume = 16 + (transfer<<6)/MAXSPEED) > 64) volume = 64;
- PlaySound(&audioinfo[COLLIDE],volume);
- if (packstate==RACKED) packstate=BROKEN;
- }
- /* Check for a foul shot here */
- if (i==CUE && !firsthit) firsthit=j;
- }
-
- /*********************/
- #define ENCRYPTCODE 0xd6
-
- long MyRead(fh,ptr,len)
- struct FileHandle *fh;
- long *ptr;
- long len;
- {
- long retnlen;
-
- retnlen = Read((BPTR)fh,ptr,len);
- len = retnlen;
- {
- register char *ptr2 = (char *)ptr;
-
- while (len > 3)
- {
- *ptr2++ ^= ENCRYPTCODE; *ptr2++ ^= ENCRYPTCODE;
- *ptr2++ ^= ENCRYPTCODE; *ptr2++ ^= ENCRYPTCODE;
- len -= 4;
- }
- while (len) { *ptr2++ ^= ENCRYPTCODE; len--; }
- }
- return retnlen;
- }
-